﻿using System;

namespace IWMAG.Core.EnhancedProperties.PropertyNodes
{
    internal class ComputedNode<T> : PropertyNode<T>
    {
        private Func<T, T> ComputeDelegate { get; set; }
        private T LastVal;
        private bool LastValSet = false;
        public void SetNodeComputation(Func<T, T> computeDelegate)
        {
            this.ComputeDelegate = computeDelegate;
            LastValSet = false;
            if (ComputeDelegate != null)
            {
                LastVal = ComputeDelegate(Next.GetNodeValue());
              
            }
            else
            {
                LastVal = Next.GetNodeValue();
            }



            LastValSet = true;
            Previous.SuccessorChanged(LastVal);
        }
        public ComputedNode(int priority, Func<T, T> computeDelegate)
            : base(priority)
        {
            this.ComputeDelegate = computeDelegate;
        }
        public override T GetNodeValue()
        {
            if (LastValSet)
            {
                return LastVal;
            }

            var temp = Next.GetNodeValue();

            if (ComputeDelegate == null)
            {
                LastVal = temp;
                LastValSet = true;
            }
            else
            {
                LastVal = ComputeDelegate(temp);
                LastValSet = true;
            }

            
            return LastVal;
        }

        public override void SuccessorChanged(T value)
        {
            LastValSet = false;
            if (ComputeDelegate == null)
            {
                LastVal = value;
                LastValSet = true;
            }
            else
            {
                LastVal = ComputeDelegate(value);
                LastValSet = true;
            }
            Previous.SuccessorChanged(LastVal);

        }

        public override void Dispose()
        {
            base.Dispose();
            ComputeDelegate = null;
            if (LastVal is IDisposable)
            {
                (LastVal as IDisposable).Dispose();
            }
            LastVal = default(T);
            
        }
    }

   
}


